import { Model, DataTypes, Optional } from 'sequelize';
import bcrypt from 'bcryptjs';
import sequelize from '@/config/database';
import Dept from './dept.model';

// 定义用户属性接口
interface UserAttributes {
  userId: number;
  deptId?: number;
  userName: string;
  nickName?: string;
  email?: string;
  phonenumber?: string;
  sex?: string;
  avatar?: string;
  password: string;
  status?: string;
  delFlag?: string;
  loginIp?: string;
  loginDate?: Date;
  createBy?: string;
  createTime?: Date;
  updateBy?: string;
  updateTime?: Date;
  remark?: string;
  dept?: any;
  roles?: any[];
  posts?: any[];
  roleIds?: number[];
  postIds?: number[];
  roleId?: number;
  admin?: boolean;
}

// 创建时可选的字段
interface UserCreationAttributes extends Optional<UserAttributes, 'userId'> {}

// 用户模型类
class User extends Model<UserAttributes, UserCreationAttributes> implements UserAttributes {
  public userId!: number;
  public deptId?: number;
  public userName!: string;
  public nickName?: string;
  public email?: string;
  public phonenumber?: string;
  public sex?: string;
  public avatar?: string;
  public password!: string;
  public status?: string;
  public delFlag?: string;
  public loginIp?: string;
  public loginDate?: Date;
  public createBy?: string;
  public createTime?: Date;
  public updateBy?: string;
  public updateTime?: Date;
  public remark?: string;
  public dept?: any;
  public roles?: any[];
  public posts?: any[];
  public roleIds?: number[];
  public postIds?: number[];
  public roleId?: number;
  public admin?: boolean;

  // 时间戳
  public readonly createdAt!: Date;
  public readonly updatedAt!: Date;

  // 密码验证方法
  public validatePassword(password: string): boolean {
    return bcrypt.compareSync(password, this.password);
  }

  // 检查用户状态是否正常
  public isActive(): boolean {
    return this.status === '0' && this.delFlag === '0';
  }
}

User.init(
  {
    userId: {
      type: DataTypes.BIGINT,
      primaryKey: true,
      autoIncrement: true,
			field: "user_id",
			get() {
				// 确保返回数字类型
				const value = this.getDataValue("userId");
				return value !== undefined ? Number(value) : undefined;
			},
    },
    deptId: {
      type: DataTypes.BIGINT,
			field: "dept_id",
			get() {
				// 确保返回数字类型
				const value = this.getDataValue("deptId");
				return value !== undefined && value !== null ? Number(value) : null;
			},
    },
    userName: {
      type: DataTypes.STRING(30),
      allowNull: false,
			field: "user_name",
			unique: true,
    },
    nickName: {
      type: DataTypes.STRING(30),
			field: "nick_name",
    },
    email: {
      type: DataTypes.STRING(50),
			defaultValue: "",
    },
    phonenumber: {
      type: DataTypes.STRING(11),
			defaultValue: "",
    },
    sex: {
      type: DataTypes.CHAR(1),
			defaultValue: "0",
    },
    avatar: {
      type: DataTypes.STRING(100),
			defaultValue: "",
    },
    password: {
      type: DataTypes.STRING(100),
      allowNull: false,
      set(value: string) {
        // 密码加密存储
        const salt = bcrypt.genSaltSync(10);
        const hash = bcrypt.hashSync(value, salt);
				this.setDataValue("password", hash);
			},
    },
    status: {
      type: DataTypes.CHAR(1),
			defaultValue: "0", // 0正常 1停用
    },
    delFlag: {
      type: DataTypes.CHAR(1),
			defaultValue: "0", // 0存在 2删除
			field: "del_flag",
    },
    loginIp: {
      type: DataTypes.STRING(128),
			field: "login_ip",
    },
    loginDate: {
      type: DataTypes.DATE,
			field: "login_date",
    },
    createBy: {
      type: DataTypes.STRING(64),
			field: "create_by",
    },
    createTime: {
      type: DataTypes.DATE,
			field: "create_time",
    },
    updateBy: {
      type: DataTypes.STRING(64),
			field: "update_by",
    },
    updateTime: {
      type: DataTypes.DATE,
			field: "update_time",
		},
		remark: {
			type: DataTypes.STRING(500),
			defaultValue: null,
		},
  },
  {
    sequelize,
		tableName: "sys_user",
    timestamps: true,
		createdAt: "createTime",
		updatedAt: "updateTime",
  }
);

// 定义与部门的关联关系
User.belongsTo(Dept, {
  foreignKey: 'deptId',
  as: 'dept'
});

export default User;